package com.edu.test.reflect.edu03;

import cn.hutool.core.convert.Convert;
import com.edu.test.dbf.DbfMain;
import org.jsoup.select.Evaluator;

import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @作者 five-five
 * @创建时间 2020/12/24
 */
public class ReflectUtil {
    //属性容器(类的所有属性)
    private static List<Field> fields = new ArrayList<>();

    /**
     * 根据properties文件进行对象属性的映射
     *
     * @param p1Path    列到对象属性
     * @param p2Path    对象属性的类型
     * @param t         对象类型
     * @param <T>       对象类型
     * @return
     * @throws Exception
     */
    public static <T> List<T> valueToPOJO(String p1Path, String p2Path, T t, List<Map<String, Object>> dateList) throws Exception {
        List<T> list = new ArrayList<>();
        //列：：属性
        Properties p1 = new Properties();
        p1.load(new FileInputStream(p1Path));
        //属性：：类型
        Properties p2 = new Properties();
        p2.load(new FileInputStream(p2Path));
        //开始干活
        Class<?> aClass = t.getClass();
        //所有属性
        List<Field> allFields = getAllFields(aClass);
        //所有数据准备完成,开始做数据
        for (Map<String, Object> map : dateList) {
            Set<String> keySet = map.keySet();
            //临时变量
            T instance = (T) aClass.getConstructor().newInstance();
            for (String key : keySet) {
                if (p1.containsKey(key)) {
                    String fieldName = p1.get(key).toString();//列名
                    //迭代属性
                    for (Field field : fields) {
                        if (field.getName().equalsIgnoreCase(fieldName)) {
                            //进行赋值
                            field.setAccessible(true);
                            //填充属性
                            field.set(instance, castByType(map.get(key), Convert.toStr(p2.get(p1.get(key)))));
                        }
                    }
                }
            }
            //添加至集合
            list.add(instance);
        }
        return list;
    }


    /**
     * 根据Type来进行值的转换
     *
     * @param s
     * @param o
     * @return
     */
    private static Object castByType(Object s, String o) {
        Class<?> aClass = null;
        try {
            aClass = Class.forName(o.trim());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return Convert.convertQuietly(aClass, s);
    }


    /**
     * 使用递归把对象及其父类的属性都拿到
     *
     * @param t
     */
    private static List<Field> getAllFields(Class t) {
        //先把自己的属性打印出来
        Field[] declaredFields = t.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            fields.add(declaredField);
        }
        Class<?> superclass = t.getSuperclass();
        if (superclass == null) {
            return fields;
        }
        return getAllFields(superclass);
    }
}
